<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>generator函数详解</title>
</head>
<body>
    <script>
        /**
         * generator函数第一次调用返回一个迭代器，并没有执行任何函数语句
         * 迭代器调用next执行语句，遇到yield或return停下
         * 返回
         *    done：表示函数是否执行完成
         *    value: yiled或者return语句后表达式的值
         * yield表达式的值是下一次调用next传入的值, 什么时候调用下一次next? 在yield后
         * 的同步或异步表达式完成之后再调用下一次next
         * async...await是generator函数语法糖，自带执行器
         */
        let delay = function(ms){
            return new Promise((resolve, reject)=>{
                setTimeout(()=>{
                    resolve(ms);
                }, ms);
            })
        }
        function * func(){
            let result1 = yield 1;
            console.log('result1...', result1);
            let result2 = yield 2;
            console.log('result2...', result2);
            let result3 = yield 3;
            console.log('result3...', result3); 
            let result4 = yield delay(1000);
            console.log('result4...', result4); 

            return 4;
        }
        // var g = func();
        // console.log('g...', g);
        // console.log('g...', g.next(100));
        // console.log('g...', g.next(200));
        // console.log('g...', g.next(300));
        // console.log('g...', g.next(400));

        function co(func){
            let g = func();
            function run(preValue){
                let {done, value} = g.next(preValue);
                if (!done){
                    if (typeof value.then === 'function'){
                        // 处理value是promise的情况
                        value.then(res=>{
                            run(res);   
                        })
                    }else{
                        run(value);
                    }
                }
            }
            run();
        }
        co(func);
    </script>
</body>
</html>